import inspect
from enum import Enum, unique, EnumMeta


from .fast_enum import KeyDescriptionEnum


class EnumWithDisplayMeta(EnumMeta):
    def __new__(mcs, name, bases, attrs):
        display_strings = attrs.get("DisplayStrings")

        if display_strings is not None and inspect.isclass(display_strings):
            del attrs["DisplayStrings"]
            if hasattr(attrs, "_member_names"):
                attrs._member_names.remove("DisplayStrings")

        obj = super().__new__(mcs, name, bases, attrs)
        for m in obj:
            m.display_string = getattr(display_strings, m.name, None)

        return obj


class ExtraEnum(Enum):
    @classmethod
    def get_info(cls, title="", list_str=False):
        str_info = """
        """
        str_info += title
        if list_str:
            for name, member in cls.__members__.items():
                str_info += """
            %s
            """ % (
                    name.lower().replace("_", "."),
                )
        else:
            for name, member in cls.__members__.items():
                str_info += """
            %s: %s
            """ % (
                    member.value,
                    name,
                )
        return str_info

    @classmethod
    def to_choices(cls, string_as_value=False):
        if string_as_value:
            choices = [
                (name.lower().replace("_", "."), name) for name, member in cls.__members__.items()
            ]
        else:
            choices = [(member.value, name) for name, member in cls.__members__.items()]

        return choices

    @classmethod
    def values(cls):
        return list(map(lambda c: c.value, cls.__members__.values()))

    @classmethod
    def names(cls):
        return [name.lower() for name, _ in cls.__members__.items()]


@unique
class ErrorCode(Enum, metaclass=EnumWithDisplayMeta):
    Unknown = 20000
    ResourceNotFound = 20001
    CustomError = 20002
    ResourceExisted = 20003
    ValidationError = 20004
    ParseError = 20005

    class DisplayStrings:
        Unknown = "未知错误"
        ResourceNotFound = "资源未找到"
        CustomError = "自定义错误"
        ResourceExisted = "资源已经存在"
        ValidationError = "参数验证错误"
        ParseError = "解析错误"

    @classmethod
    def get_info(cls):
        error_code_str = """
        Error Codes:
        """
        for name, member in cls.__members__.items():
            error_code_str += """
            %s: %s
            """ % (
                member.value,
                member.display_string,
            )

        return error_code_str


class BulkOperations(KeyDescriptionEnum):
    CREATE = "create", "创建"
    UPDATE = "update", "更新"
    DELETE = "delete", "删除"


@unique
class PointRules(ExtraEnum):
    Voucher = "Voucher"  # 抵扣


class BasketType(KeyDescriptionEnum):
    PRE = "Pre", "预购物车"
    FINAL = "Final", "最终购物车"


class PriceType(KeyDescriptionEnum):
    POINT = "Point", "积分"
    RMB = "Rmb", "人民币"


class OrderStatus(KeyDescriptionEnum):
    ORDERED = "Ordered", "下单待审批"
    SELECT_PAY_METHOD = "SelectPayMethod", "待选择支付方式"
    TO_BE_PAID = "ToBePaid", "待付款"
    PAID_TO_BE_CONFIRMED = "PaidToBeConfirmed", "支付凭证已上传待审批"
    CONFIRMED = "Confirmed", "已通过"
    REJECTED = "Rejected", "已拒绝"
    TIMEOUT_CANCELLED = "TimeoutCancelled", "已取消（超时未支付）"
    # APPLY_REFUND = "ApplyRefund", "微信申请退款"
    # CONFIRMED_REFUND = "ConfirmedRefund", "微信退款申请通过"
    # REFUNDED = "Refunded", "微信已退款"


class MediaType(KeyDescriptionEnum):
    IMAGE = "image", "图片"
    VIDEO = "video", "视频"


class FilePurpose(KeyDescriptionEnum):
    DESCRIPTION = "description", "描述"
    LIST_HEADER = "ListHeader", "列表头图"
    HEADER_ADVERTISEMENT = "header_advertisement", "顶部广告"
    UPLOAD = "upload", "上传视频"
